/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import org.eclipse.jface.action.IMenuCreator; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MenuAdapter; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.IWorkbenchCommandConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; /** * The <code>NavigationHistoryAction</code> moves navigation history * back and forward. */ public class NavigationHistoryAction extends PageEventAction { private boolean recreateMenu; private boolean forward; private Menu historyMenu; private int MAX_HISTORY_LENGTH = 9; private class MenuCreator implements IMenuCreator { public void dispose() { } public Menu getMenu(Menu parent) { setMenu(new Menu(parent)); fillMenu(historyMenu); initMenu(); return historyMenu; } public Menu getMenu(Control parent) { setMenu(new Menu(parent)); fillMenu(historyMenu); initMenu(); return historyMenu; } } private void setMenu(Menu menu) { historyMenu = menu; } private void initMenu() { historyMenu.addMenuListener(new MenuAdapter() { public void menuShown(MenuEvent e) { if (recreateMenu) { Menu m = (Menu) e.widget; MenuItem[] items = m.getItems(); for (int i = 0; i < items.length; i++) { items[i].dispose(); } fillMenu(m); } } }); } private void fillMenu(Menu menu) { IWorkbenchPage page = getWorkbenchWindow().getActivePage(); if (page == null) { return; } final NavigationHistory history = (NavigationHistory) getWorkbenchWindow() .getActivePage().getNavigationHistory(); NavigationHistoryEntry[] entries; if (forward) { entries = history.getForwardEntries(); } else { entries = history.getBackwardEntries(); } int entriesCount[] = new int[entries.length]; for (int i = 0; i < entriesCount.length; i++) { entriesCount[i] = 1; } entries = collapseEntries(entries, entriesCount); for (int i = 0; i < entries.length; i++) { if (i > MAX_HISTORY_LENGTH) { break; } String text = entries[i].getHistoryText(); if (text != null) { MenuItem item = new MenuItem(menu, SWT.NONE); item.setData(entries[i]); if (entriesCount[i] > 1) { text = NLS.bind(WorkbenchMessages.get().NavigationHistoryAction_locations,text, new Integer(entriesCount[i])); } item.setText(text); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { history .shiftCurrentEntry( (NavigationHistoryEntry) e.widget .getData(), forward); } }); } } recreateMenu = false; } public void dispose() { super.dispose(); if (historyMenu != null) { for (int i = 0; i < historyMenu.getItemCount(); i++) { MenuItem menuItem = historyMenu.getItem(i); menuItem.dispose(); } historyMenu.dispose(); historyMenu = null; } } /** * Create a new instance of <code>NavigationHistoryAction</code> * * @param window * the workbench window this action applies to * @param forward * if this action should move history forward of backward */ public NavigationHistoryAction(IWorkbenchWindow window, boolean forward) { super("", window); //$NON-NLS-1$ ISharedImages sharedImages = window.getWorkbench().getSharedImages(); if (forward) { setText(WorkbenchMessages.get().NavigationHistoryAction_forward_text); setToolTipText(WorkbenchMessages.get().NavigationHistoryAction_forward_toolTip); // @issue missing action id window.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.NAVIGATION_HISTORY_FORWARD); setImageDescriptor(sharedImages .getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD)); setDisabledImageDescriptor(sharedImages .getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD_DISABLED)); setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_FORWARD_HISTORY); } else { setText(WorkbenchMessages.get().NavigationHistoryAction_backward_text); setToolTipText(WorkbenchMessages.get().NavigationHistoryAction_backward_toolTip); // @issue missing action id window.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.NAVIGATION_HISTORY_BACKWARD); setImageDescriptor(sharedImages .getImageDescriptor(ISharedImages.IMG_TOOL_BACK)); setDisabledImageDescriptor(sharedImages .getImageDescriptor(ISharedImages.IMG_TOOL_BACK_DISABLED)); setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_BACKWARD_HISTORY); } // WorkbenchHelp.setHelp(this, IHelpContextIds.CLOSE_ALL_PAGES_ACTION); setEnabled(false); this.forward = forward; setMenuCreator(new MenuCreator()); } /* (non-Javadoc) * Method declared on PageEventAction. */ public void pageClosed(IWorkbenchPage page) { super.pageClosed(page); setEnabled(false); } private NavigationHistoryEntry[] collapseEntries( NavigationHistoryEntry[] entries, int entriesCount[]) { ArrayList allEntries = new ArrayList(Arrays.asList(entries)); NavigationHistoryEntry previousEntry = null; int i = -1; for (Iterator iter = allEntries.iterator(); iter.hasNext();) { NavigationHistoryEntry entry = (NavigationHistoryEntry) iter.next(); if (previousEntry != null) { String text = previousEntry.getHistoryText(); if (text != null) { if (text.equals(entry.getHistoryText()) && previousEntry.editorInfo == entry.editorInfo) { iter.remove(); entriesCount[i]++; continue; } } } previousEntry = entry; i++; } entries = new NavigationHistoryEntry[allEntries.size()]; return (NavigationHistoryEntry[]) allEntries.toArray(entries); } /* (non-Javadoc) * Method declared on PageEventAction. */ public void pageActivated(IWorkbenchPage page) { super.pageActivated(page); NavigationHistory nh = (NavigationHistory) page.getNavigationHistory(); if (forward) { nh.setForwardAction(this); } else { nh.setBackwardAction(this); } } /* (non-Javadoc) * Method declared on IAction. */ public void run() { if (getWorkbenchWindow() == null) { // action has been disposed return; } IWorkbenchPage page = getActivePage(); if (page != null) { NavigationHistory nh = (NavigationHistory) page .getNavigationHistory(); if (forward) { nh.forward(); } else { nh.backward(); } recreateMenu = true; } } public void update() { // Set the enabled state of the action and set the tool tip text. The tool tip // text is set to reflect the item that one will move back/forward to. WorkbenchPage page = (WorkbenchPage) getActivePage(); if (page == null) { return; } NavigationHistory history = (NavigationHistory) page .getNavigationHistory(); NavigationHistoryEntry[] entries; if (forward) { setEnabled(history.canForward()); entries = history.getForwardEntries(); if (entries.length > 0) { NavigationHistoryEntry entry = entries[0]; String text = NLS.bind(WorkbenchMessages.get().NavigationHistoryAction_forward_toolTipName, entry.getHistoryText() ); setToolTipText(text); } else { setToolTipText(WorkbenchMessages.get().NavigationHistoryAction_forward_toolTip); } } else { setEnabled(history.canBackward()); entries = history.getBackwardEntries(); if (entries.length > 0) { NavigationHistoryEntry entry = entries[0]; String text = NLS.bind(WorkbenchMessages.get().NavigationHistoryAction_backward_toolTipName, entry.getHistoryText() ); setToolTipText(text); } else { setToolTipText(WorkbenchMessages.get().NavigationHistoryAction_backward_toolTip); } } recreateMenu = true; } }